﻿using System;
using System.Runtime.InteropServices;
using SoundCodec.Lame;

namespace SoundCodec
{
    public enum ErrorCodes
    {
        BE_ERR_SUCCESSFUL =                     0,
        BE_ERR_INVALID_FORMAT =                 1,
        BE_ERR_INVALID_FORMAT_PARAMETERS =      2,
        BE_ERR_NO_MORE_HANDLES =                3,
        BE_ERR_INVALID_HANDLE =                 4
    }
    public class LameEnc
    {
        public LameEnc()
        {
        }

        #region DLLImports (lame_enc.dll)
        /// <summary>
        /// This function is the first to call before starting an encoding stream.
        /// </summary>
        /// <param name="pbeConfig">Pointer at the struct containing encoder settings.</param>
        /// <param name="dwSampled">Pointer at double word where number of samples to send to each beEncodeChunk() is returned.</param>
        /// <param name="dwBufferSize">Pointer at double word where minimum size in bytes of output buffer is returned.</param>
        /// <param name="phbeStream">Pointer at integer where Stream handle is returned.</param>
        /// <returns>Error code</returns>
        [DllImport("lame_enc.dll")]
        public static extern uint beInitStream(BE_CONFIG pbeConfig, ref uint dwSampled, ref uint dwBufferSize, ref uint phbeStream);

        /// <summary>
        /// This function should be called after encoding the last chunk in order to flush the encoder. It writes any encoded data that still might be left inside the encoder to the output buffer. This function should NOT be called unless you have encoded all of the chunks in your stream.
        /// </summary>
        /// <param name="hbeStream">Handle of the stream.</param>
        /// <param name="pOutput">Where to write the encoded data. This buffer should be at least of the minimum size returned by beInitStream().</param>
        /// <param name="pdwOutput">Where to return number of bytes of encoded data written.</param>
        /// <returns>Error code</returns>
        [DllImport("lame_enc.dll")]
        public static extern uint beDeinitStream(uint hbeStream, [In, Out] byte[] pOutput, uint pdwOutput);

        /// <summary>
        /// Last function to be called when finished encoding a stream. Should unlike beDeinitStream()  also be called if the encoding is canceled.
        /// </summary>
        /// <param name="hbeStream">Handle of the stream.</param>
        /// <returns>Error code</returns>
        [DllImport("lame_enc.dll")]
        public static extern uint beCloseStream(uint hbeStream);

        /// <summary>
        /// Encodes a chunk of samples. Please note that if you have set the output to generate mono MP3 files you must feed beEncodeChunk() with mono samples!
        /// </summary>
        /// <param name="hbeStream">Handle of the stream.</param>
        /// <param name="nSamples">Number of samples to be encoded for this call. This should be identical to what is returned by beInitStream(), unless you are encoding the last chunk, which might be smaller.</param>
        /// <param name="pSamples">Pointer at the 16-bit signed samples to be encoded. These should be in stereo when encoding a stereo MP3 and mono when encoding a mono MP3</param>
        /// <param name="pOutput">Where to write the encoded data. This buffer should be at least of the minimum size returned by beInitStream().</param>
        /// <param name="pdwOutput">Where to return number of bytes of encoded data written. The amount of data written might vary from chunk to chunk.</param>
        /// <returns>Error code</returns>
        [DllImport("lame_enc.dll")]
        public static extern uint beEncodeChunk(uint hbeStream, ulong nSamples, short[] pSamples, [In, Out] byte[] pOutput, ulong[] pdwOutput);
        #endregion
    }
}
